home *** CD-ROM | disk | FTP | other *** search
- /*
- * Data functions.
- *
- */
-
- #include "hc.h"
-
- struct CircBuffer
- {
- UBYTE Mem[4096];
- UWORD Read;
- UWORD Write;
- UWORD Size;
- UWORD OverRun;
- };
-
- void WriteData (struct CircBuffer *, UWORD);
- void ServeWaiter (void);
- UWORD Truth (UWORD Value, UBYTE *Buffer);
-
- static struct CircBuffer *FileBuffer;
- static UBYTE *WriteBuffer[2];
- static UWORD FreeBuffer, Modem = 1, ToHC, FromHC;
-
- /*
- * UWORD OpenData (void) void CloseData (void)
- *
- * Alloc and free the memory needed for data manipulation.
- */
-
- UWORD OpenData (void)
- {
- FileBuffer = AllocMem (sizeof (struct CircBuffer) * NUM_HC, MEMF_CLEAR);
- if (FileBuffer)
- {
- WriteBuffer[0] = AllocMem (4096, 0L);
- if (WriteBuffer[0])
- {
- WriteBuffer[1] = AllocMem (4096, 0L);
- if (WriteBuffer[1])
- {
- return 1;
- }
- }
- }
- DB else
- DB {
- DB Say ("FileBuffer allocation failed.\n");
- DB }
-
- CloseData ();
- return 0;
- }
-
- void CloseData (void)
- {
- if (WriteBuffer[1]) FreeMem (WriteBuffer[1], 4096);
- if (WriteBuffer[0]) FreeMem (WriteBuffer[0], 4096);
- if (FileBuffer) FreeMem (FileBuffer, sizeof (struct CircBuffer) * NUM_HC);
-
- FileBuffer = NULL;
- WriteBuffer[0] = NULL;
- WriteBuffer[1] = NULL;
- }
-
-
- /*
- * UWORD PutData (UWORD File, UBYTE *Buffer, UWORD Size)
- *
- * Put a HC11 address between each byte sent to the serial port. The
- * address is a lower nibble containing the id of the sender and a
- * higher nibble containg the id of the receiver.
- */
-
- UWORD PutData (UWORD File, UBYTE *Buffer, UWORD Size)
- {
- UWORD SizeCount;
- UWORD BufferCount;
-
- if (File == BAUD)
- {
- SetBaud (atoi (Buffer));
- return Size;
- }
- else if (File == FROM)
- {
- FromHC = Truth (FromHC, Buffer);
- return Size;
- }
- else if (File == TO)
- {
- ToHC = Truth (ToHC, Buffer);
- return Size;
- }
- else if (File == MODEM)
- {
- Modem = Truth (Modem, Buffer);
- return Size;
- }
- else if (File > 0 && File <= NUM_HC)
- {
-
- File = (File << 3) | 0x80;
- SizeCount = Size;
- BufferCount = 0;
-
- while (SizeCount--)
- {
- if (ToHC)
- {
- DB sprintf (dbi.Msg, "Sending file iden byte: %x.\n", File);
- DB Say (dbi.Msg);
- WriteBuffer[FreeBuffer][BufferCount++] = File;
- }
-
- if (Modem == 1 && *Buffer == 10)
- *Buffer = 13;
-
- WriteBuffer[FreeBuffer][BufferCount++] = *Buffer++;
- if (BufferCount == 4096)
- {
- WriteSer (WriteBuffer[FreeBuffer], 4096);
- BufferCount = 0;
- FreeBuffer = (FreeBuffer + 1) & 1;
- }
- }
-
- if (BufferCount)
- {
- WriteSer (WriteBuffer[FreeBuffer], BufferCount);
- FreeBuffer = (FreeBuffer + 1) & 1;
- }
-
- return Size;
- }
- else
- {
- return 0;
- }
- }
-
-
- /*
- * UWORD Truth (UWORD Value, UBYTE *Buffer)
- *
- * Check the truth contained in a string, and return true, false or the
- * old value.
- */
-
- UWORD Truth (UWORD Value, UBYTE *Buffer)
- {
- if (*Buffer == '0')
- return 0;
- else if (*Buffer == '1')
- return 1;
- else
- return Value;
- }
-
-
- /*
- * UWORD GetData (UWORD File, UBYTE *Buffer, UWORD Size)
- *
- * Check which file is read and take that much data from the buffers.
- * They are filled by the serial routines.
- */
-
- UWORD GetData (UWORD File, UBYTE *Buffer, UWORD Size)
- {
- struct CircBuffer *b;
- UWORD rcount = Size;
-
- if (File == 0 || File > NUM_HC)
- return 0;
-
- /*
- * Get the data associated with the file number.
- */
-
- b = &FileBuffer[File - 1];
-
- /*
- * No data -> wait for more by return ing minus one (-1).
- */
-
- if (0 == b->Size)
- return -1;
-
- /*
- * Transfer as much as we have.
- */
-
- while (rcount > 0 && b->Size > 0)
- {
- *Buffer++ = b->Mem[b->Read++];
- b->Read &= 0x0fff;
- rcount--;
- b->Size--;
- }
-
- return Size - rcount;
- }
-
-
- /*
- * UWORD DataSize (UWORD File)
- *
- * Return the current size of the file, which is the amount of data
- * pending in the circular buffer.
- */
-
- UWORD DataSize (UWORD File)
- {
- switch (File)
- {
- case ROOT:
- return 0;
- case MODEM:
- return Modem;
- case FROM:
- return FromHC;
- case TO:
- return ToHC;
- case BAUD:
- return GetBaud ();
- case HC1:
- case HC2:
- case HC3:
- case HC4:
- case HC5:
- case HC6:
- case LOOP:
- return FileBuffer[File-1].Size;
- default:
- return -1;
- }
- }
-
-
- /*
- * void ClassData (UBYTE *Buffer, UWORD Size)
- *
- * This parse a buffer as pairs of bytes. The first byte contain the
- * id of the sender in the low nibble and the id of the receiver in
- * the high nibble.
- *
- * If the data is ours (id == 0), then we put the data in the second
- * byte in its buffer, if it's for someone else (id != 0), we resend
- * it out of the srial port.
- *
- * The code check for over-run of the circular buffer for each id and
- * set the head of the read in accordance to the new position of the
- * write head.
- */
-
- void ClassData (UBYTE *Buffer, UWORD Size)
- {
- UWORD i;
-
- if (FromHC)
- {
- while (Size > 1)
- {
- i = (UWORD)Buffer[0];
- if (i & 0x80)
- {
- i &= 0x3F;
- if (i > 0 && i <= NUM_HC)
- {
- DB Say ("Data decoded from HC11.\n");
- WriteData (&FileBuffer[i - 1], (UWORD)Buffer[1]);
- }
- else if (i & 0x07)
- {
- DB sprintf (dbi.Msg, "Data passing through (i == %x).\n", i);
- DB Say (dbi.Msg);
- // WriteSer (Buffer, 2);
- }
- else
- {
- /*
- * Data we sent somehow looped the loop...
- */
- DB Say ("Data looped around.\n");
- WriteData (&FileBuffer[LOOP-1], (UWORD)Buffer[1]);
- }
- Size -= 2;
- Buffer += 2;
- }
- else
- {
- DB Say ("Trying to synchronize.\n");
- SyncSer ();
- Size -= 1;
- Buffer += 1;
- }
- }
- }
- else
- {
- while (Size--)
- {
- WriteData (FileBuffer, (UWORD)*Buffer);
- Buffer++;
- }
- }
-
- for (i = 0; i < NUM_HC; i++)
- {
- if (FileBuffer[i].OverRun)
- {
- FileBuffer[i].Read = (FileBuffer[i].Write + 1) & 0x0fff;
- FileBuffer[i].OverRun = 0;
- }
- }
-
- ServeWaiter ();
- }
-
-
- /*
- * void WriteData (struct CircBuffer *b, UWORD c)
- *
- * Put a byte of data in a circular buffer and check for overflow.
- */
-
- void WriteData (struct CircBuffer *b, UWORD c)
- {
- if (Modem == 1)
- {
- if (c == 10)
- return;
- else if (c == 13)
- c = 10;
- }
- b->Mem[b->Write++] = c;
- b->Write &= 0x0fff;
- if (b->Write == b->Read)
- b->OverRun = 1;
- b->Size = (b->Size + 1) & 0x0FFF;
- }
-
-
- /*
- * void ServeWaiter (void)
- *
- * Serve packets that are waiting for data. The REALLY nice thing here
- * is that since the packet was waiting, no data was in the buffer, and
- * since this function is called by ClassData, which is itself always
- * called when there's been 4096 bytes of data (maximum) arrived, we're
- * sure that we lose no data...
- */
-
- void ServeWaiter (void)
- {
- struct DosPacket *Packet;
- struct Node *Node, *Next;
-
- DB Say ("Serving waiters.\n");
-
- for (Node = ReadList.lh_Head; Node->ln_Succ != NULL; Node = Next)
- {
- Next = Node->ln_Succ;
- Packet = (struct DosPacket *)Node->ln_Name;
- if (Packet != NULL)
- {
- if (FileBuffer[Packet->dp_Arg1 - 1].Size > 0)
- {
- DB Say ("Replying to waiter.\n");
- Remove (Node);
- Packet->dp_Res1 = GetData (Packet->dp_Arg1, (UBYTE *)Packet->dp_Arg2, Packet->dp_Arg3);
- ReturnPacket (Packet, Process);
- }
- }
- }
- }
-